package com.shenmazong.servereduuser.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shenmazong.servereduuser.entity.TbUser;
import com.shenmazong.servereduuser.mapper.TbUserMapper;
import com.shenmazong.servereduuser.service.ITbUserService;
import com.shenmazong.servereduuser.utils.AuthCodeUtil;
import com.shenmazong.servereduuser.vo.UserVo;
import com.shenmazong.utils.Idutils;
import com.shenmazong.utils.JwtUtils;
import com.shenmazong.utils.ResultResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 关好帅
 * @since 2021-09-14
 */
@Service
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser> implements ITbUserService {
    @Autowired
    private TbUserMapper userMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public ResultResponse login(TbUser user) {
        TbUser u = userMapper.selectOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserName, user.getUserName()).last("limit 1")
        );

        if(u==null){
             u = userMapper.selectOne(
                    new QueryWrapper<TbUser>().lambda().eq(TbUser::getEmail, user.getUserName()).last("limit 1")
            );
        }

        if(u==null){
            u = userMapper.selectOne(
                    new QueryWrapper<TbUser>().lambda().eq(TbUser::getPhone, user.getUserName()).last("limit 1")
            );
        }

        if(u==null){
            return ResultResponse.FAILED(-1,"用户名不存在");
        }
        //获取密码 以及加密的时候的盐
        String base = user.getUserPass()+u.getSalt();
        //
        String pass = DigestUtils.md5DigestAsHex(base.getBytes());

        if(!u.getUserPass().equals(pass)){
            return ResultResponse.FAILED(-2,"密码错误");
        }
//
        //密码账号都正确时生成token
        String token = JwtUtils.makeToken(u.getUserId(), user.getUserName(), null);
        HashMap<String, Object> dataMap = new HashMap<>();
        dataMap.put("accessToken", token);
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        opsForValue.set(u.getUserId()+"",token,1,TimeUnit.MINUTES);
        opsForValue.set(token,token);
        return ResultResponse.SUCCESS(dataMap);
    }

    @Override
    public ResultResponse register(UserVo user) {
        //判断验证码输入是否错误
        String code = stringRedisTemplate.opsForValue().get("userPhone:"+ user.getPhone());
        if(code==null){
            return ResultResponse.FAILED(-1,"验证码已失效");
        }

        if(!code.equals(user.getPhoneCode())){
            return ResultResponse.FAILED(-2,"验证码输入错误");
        }
        Long id = Idutils.getId();
        String uu = UUID.randomUUID().toString().substring(0,10);
        String salt = uu.replaceAll("-", "");
        System.err.println(salt.length());
        user.setUserId(id);
        user.setSalt(salt);
        String userPass = user.getUserPass();
        String pass = DigestUtils.md5DigestAsHex((userPass + salt).getBytes());
        user.setUserPass(pass);
        TbUser tbUser=new TbUser();
        BeanUtils.copyProperties(user,tbUser);
        userMapper.insert(tbUser);
        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse sendCode(String phone) {
        String code = AuthCodeUtil.getCode("a-zA-Z0-9", 6);
        try {
            AuthCodeUtil.sendMsgToPhone(code,phone);
            stringRedisTemplate.opsForValue().set("userPhone:"+phone,code,2,TimeUnit.MINUTES);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.FAILED(-1,"发送失败");
        }
        return ResultResponse.SUCCESS();
    }
}
